<template>
  <div ref="chart" style="width: 100%; height: 100%;"></div>
</template>

<script>
import * as echarts from 'echarts'
import elementResizeDetectorMaker from 'element-resize-detector'
import MapCenterClick from '@/mixins/map-center-click'
import { COAL, COAL_TEXT, ELECTRIC, ELECTRIC_TEXT, GAS, GAS_TEXT } from '@/config'
import GlobalFilterListener from '@/views/visual-screen/components/GlobalFilterListener.vue'

const erd = elementResizeDetectorMaker()
const geoJSON = {
  nanchang_full: require('./nanchang_full.json'),
  nanchang: require('./nanchang.json')
}
const cs = {
  360102: '#ff4500',
  360103: '#ff8c00',
  360104: '#ffd700',
  360111: '#00ced1',
  360112: '#1e90ff',
  360113: '#90ee90',
  360121: '#c71585',
  360123: '#5470c6',
  360124: '#91cc75',
}
export default {
  name: 'map-center',
  mixins: [MapCenterClick, GlobalFilterListener],
  props: {
    map: {
      type: String,
      default: 'nanchang'
    },
    // 1-企业地图 2-区域地图 3-行业地图
    type: {
      type: String,
      default: '1'
    },
  },
  computed: {
    themeColor () {
      return this.$store.state.user.theme
    },
    enterpriseList () {
      return this.$store.state.energyEnterpriseList
    },
    enterpriseMapList () {
      return this.$store.state.enterpriseMapList
    },
    districtMapList () {
      return this.$store.state.districtMapList
    },
    industryMapList () {
      return this.$store.state.industryMapList
    },
    mapData () {
      const type = this.type
      if (type === '2') {
        return this.districtMapList
      } else if (type === '3') {
        return this.industryMapList
      } else {
        return this.enterpriseMapList
      }
    },
    scatterKey () {
      const type = this.type
      if (type === '2') {
        return 'districtBelong'
      } else if (type === '3') {
        return 'belongIndustry'
      } else {
        return 'enterpriseId'
      }
    },
    scatterData () {
      const key = this.scatterKey
      const mapData = this.mapData
      const enterpriseList = this.enterpriseList
      const lists = [...enterpriseList.filter(v => v.longitude && v.latitude).map(v => ({
        ...v,
        name: v.name,
        value: v.position,
      }))]
      const result = []
      mapData.forEach(v => {
        const value = v[key]
        const target = lists.find(vv => String(vv[key]) === String(value))
        if (target) {
          result.push({
            ...target,
            ...v,
            name: v._name || target[key + 'Name']
          })
        }
      })
      return result
    },
  },
  data () {
    return {
      chart: null,
      option: {},
      colors: { ...cs }
    }
  },
  watch: {
    scatterData: {
      deep: true,
      handler () {
        this.initScatter()
      },
    },
    colors: {
      deep: true,
      handler () {
        const chart = this.chart
        if (chart) {
          chart.setOption(this.getChartOption())
        }
      }
    }
  },
  mounted () {
    this.$store.dispatch('GET_ENTERPRISE_LIST')
    // 是哪个地图
    const type = this.type
    if (type === '1') {
      this.$store.dispatch('GET_ENTERPRISE_MAP_LIST')
    } else if (type === '2') {
      this.$store.dispatch('GET_DISTRICT_MAP_LIST')
    } else if (type === '3') {
      this.$store.dispatch('GET_INDUSTRY_MAP_LIST')
    }

    // fetch('https://geo.datav.aliyun.com/areas_v3/bound/360100_full.json').then(res => res.json())
    //   .then(data => console.log(data))
    //   .catch(err => console.log(err.message))

    echarts.registerMap(this.map, geoJSON[this.map])
    echarts.registerMap(this.map + '_full', geoJSON[this.map + '_full'])
    const chart = this.chart = echarts.init(this.$refs.chart)
    const option = this.option = this.getChartOption()
    chart.setOption(option)

    setTimeout(() => {
      this.initScatter()
    }, 200)
    erd.listenTo(this.$refs.chart, function () {
      chart.resize({
        animation: {
          duration: 1000,
        }
      })
    })
  },
  beforeDestroy () {
    erd.removeAllListeners(this.$refs.chart)
    this.timer && clearInterval(this.timer)
  },
  methods: {
    eventBusHandler ({ type, typeValue }) {
      const c = typeValue === '' ? cs : null
      if (c) {
        this.colors = Object.assign(this.colors, cs)
      } else if (type === '1') {
        const gray = Object.keys(cs).reduce((acc, vv) => {
          if (typeValue === vv) {
            acc[vv] = cs[vv]
          } else {
            acc[vv] = '#cccccc'
          }
          return acc
        }, {})
        this.colors = Object.assign(this.colors, gray)
      }
    },
    getUnitName (type) {
      const energyUnits = this.$store.state.energyUnits
      const target = energyUnits.find(v => v.key === type)
      return target ? target.value : '吨标准煤'
    },
    getChartOption () {
      const vm = this
      const getData = this.getData
      const toHTML = this.toHTML
      const regions = geoJSON[this.map + '_full'].features
      const colors = this.colors
      return {
        tooltip: {
          trigger: 'item',
          position: function (point) {
            const [x, y] = point
            return [x + 20, y - 20]
          },
        },
        geo: [
          {
            map: this.map,
            left: '2%',
            right: '2%',
            top: '2%',
            bottom: '2%',
            itemStyle: {
              areaColor: 'transparent',
              borderColor: '#50fdfc',
              borderWidth: 0,
            },
            emphasis: {
              disabled: true,
            },
            tooltip: {
              show: false,
            },
          },
          {
            map: this.map + '_full',
            left: '2%',
            right: '2%',
            top: '2%',
            bottom: '2%',
            itemStyle: {
              borderColor: cs[2],
            },
            emphasis: {
              disabled: true,
            },
            regions: [
              ...regions.map((v, i) => ({
                adcode: v.properties.adcode,
                name: v.properties.name,
                label: {
                  show: true,
                  color: '#6fdf91',
                },
                itemStyle: {
                  areaColor: colors[v.properties.adcode],
                  opacity: 0.6
                },
                emphasis: {
                  itemStyle: {
                    areaColor: colors[v.properties.adcode],
                    opacity: 1
                  }
                },
                tooltip: {
                  show: false,
                  formatter: function (params, ticket, callback) {
                    if (vm.regionName !== params.name) {
                      vm.regionHTML = '<div style="min-height: 150px;">loading...</div>'
                      getData().then(res => {
                        // TODO
                        const data = [params.name, ...res]
                        vm.regionName = params.name
                        const regionHTML = vm.regionHTML = toHTML(data)
                        callback(ticket, regionHTML)
                      })
                    }
                    return vm.regionHTML
                  },
                  backgroundColor: 'rgba(12,27,88,0.9)',
                  extraCssText: `
                    width: 400px;
                    color: #ccc;
                    border-radius: 6px;
                    box-shadow: 0 4px 10px rgba(0,0,0,0.2);
                  `
                },
              }))
            ],
          },
        ],
      }
    },
    getData (name) {
      return new Promise((resolve) => {
        const rand = () => Math.round(Math.random() * 1000)
        setTimeout(() => {
          resolve(Array(8).fill(1).map(v => rand()))
        }, 400)
      })
    },
    toHTML (data) {
      const [v1, v2, v3, v4, v5, v6, v7, v8, v9] = data
      return `
        <table class="tooltip-table">
          <caption style="line-height: 2;">${v1}（${v2}家企业）</caption>
          <thead>
            <tr>
              <td>名称</td>
              <td>数值</td>
              <td>单位</td>
            </tr>
          </thead>
          <tbody>
            <tr>
              <td>综合能源消费量</td>
              <td>${v3}</td>
              <td>万吨标准煤</td>
            </tr>
            <tr>
              <td>用电量</td>
              <td>${v4}</td>
              <td>万吨标准煤</td>
            </tr>
            <tr>
              <td>用煤量</td>
              <td>${v5}</td>
              <td>万吨标准煤</td>
            </tr>
            <tr>
              <td>万元工业总产值工业消耗</td>
              <td>${v6}</td>
              <td>千克标准煤/万元</td>
            </tr>
            <tr>
              <td>工业总产值</td>
              <td>${v7}</td>
              <td>万元</td>
            </tr>
            <tr>
              <td>工业增加值</td>
              <td>${v8}</td>
              <td>万吨标准煤</td>
            </tr>
            <tr>
              <td>万元工业增加值综合消耗</td>
              <td>${v9}</td>
              <td>千克标准煤/万元</td>
            </tr>
          </tbody>
        </table>
      `
    },
    update (option = {}) {
      if (this.chart) {
        this.chart.setOption({
          ...this.chartOption,
          ...option
        })
      }
    },
    initScatter () {
      const type = this.type
      let data = this.scatterData

      // 地图数据异常是 只撒企业点 关闭tooltip
      data = data.length > 0 ? data : this.enterpriseList

      const chart = this.chart
      let fragment1 = ''
      let fragment2 = ''
      if (type !== '1') {
        fragment1 = (data) => `
         <div style="margin: 0;line-height:1.5;"><span
                        style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:orange;"></span><span
                        style="font-size:14px;color:#666;font-weight:400;margin-left:2px">企业数量：</span><span
                    style="margin-left:10px;font-size:14px;color:#666;font-weight:900">${data.enterpriseNumber || '-'} 家</span>
                    </div>
        `
        fragment2 = (data) => `
          <div style="margin: 0;line-height:1.5;"><span
                        style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:purple;"></span><span
                        style="font-size:14px;color:#666;font-weight:400;margin-left:2px">综合能耗大户：</span><span
                    style="margin-left:10px;font-size:14px;color:#666;font-weight:900">${data.maxConsumptionEnterprise || '-'}</span>
                    </div>
        `
      }
      const option = this.option = {
        ...this.option,
        series: [
          {
            zlevel: 21,
            type: 'effectScatter',
            coordinateSystem: 'geo',
            rippleEffect: {
              number: 3,
              period: 5,
              scale: 10,
              brushType: 'stroke',
            },
            symbolSize: 5,
            itemStyle: {
              color: '#50fdfc'
            },
            label: {
              show: false,
              color: 'red',
              formatter: '{@[2]}',
            },
            emphasis: {
              label: {
                show: true,
              },
            },
            tooltip: {
              show: true,
              formatter: ({ data }) => `
                <div style="margin: 0;line-height:1;">
                  <div style="font-size:14px;color:#666;font-weight:400;line-height:1;">${data.name}</div>
                  <div style="margin: 10px 0 0;line-height:1;">
                    ${fragment1 && fragment1(data)}
                    <div style="margin: 0;line-height:1.5;"><span
                        style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:red;"></span><span
                        style="font-size:14px;color:#666;font-weight:400;margin-left:2px">总${COAL_TEXT}：</span><span
                    style="margin-left:10px;font-size:14px;color:#666;font-weight:900">${data[COAL] || '-'} ${this.getUnitName(COAL)}</span>
                    </div>
                    <div style="margin: 0;line-height:1.5;"><span
                        style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:green;"></span><span
                        style="font-size:14px;color:#666;font-weight:400;margin-left:2px">总${ELECTRIC_TEXT}：</span><span
                    style="margin-left:10px;font-size:14px;color:#666;font-weight:900">${data[ELECTRIC] || '-'} ${this.getUnitName(ELECTRIC)}</span>
                    </div>
                    <div style="margin: 0;line-height:1.5;"><span
                        style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:blue;"></span><span
                        style="font-size:14px;color:#666;font-weight:400;margin-left:2px">总${GAS_TEXT}：</span><span
                    style="margin-left:10px;font-size:14px;color:#666;font-weight:900">${data[GAS] || '-'} ${this.getUnitName(GAS)}</span>
                    </div>
                    <div style="margin: 0;line-height:1.5;"><span
                        style="display:inline-block;margin-right:4px;border-radius:10px;width:10px;height:10px;background-color:yellowgreen;"></span><span
                        style="font-size:14px;color:#666;font-weight:400;margin-left:2px">综合能耗：</span><span
                    style="margin-left:10px;font-size:14px;color:#666;font-weight:900">${data.consumption || '-'} ${this.getUnitName('other')}</span>
                    </div>
                    ${fragment2 && fragment2(data)}
                  </div>
                </div>
              `
            },
            data: [
              ...data
            ]
          },
        ],
      }
      chart.setOption(option)

      if (this.scatterData.length) {
        let i = 0
        const n = data.length
        this.timer = setInterval(() => {
          i++
          if (i >= n) {
            i = 0
          }
          if (chart) {
            chart.dispatchAction({
              type: 'showTip',
              seriesIndex: 0,
              dataIndex: i
            })
          } else {
            clearInterval(this.timer)
          }
        }, 2000)
      }
    },
  }
}
</script>
